import { BaseStorage } from './base-storage.js';

/**
 * IndexedDB存储实现
 */
export class IndexedDBStorage extends BaseStorage {
  constructor(dbName = 'yuStorageDB', storeName = 'defaultStore') {
    super('indexedDB');
    this.dbName = dbName;
    this.storeName = storeName;
    this.db = null;
  }

  /**
   * 检查IndexedDB是否可用
   * @returns {boolean} 是否可用
   */
  isAvailable() {
    return typeof indexedDB !== 'undefined';
  }

  /**
   * 初始化IndexedDB
   * @param {string} dbName - 数据库名称
   * @param {string} storeName - 存储名称
   * @returns {Promise<IDBDatabase>} 数据库实例
   */
  initIndexedDB(dbName = this.dbName, storeName = this.storeName) {
    this.dbName = dbName;
    this.storeName = storeName;
    this.db = null;

    return new Promise((resolve, reject) => {
      if (!this.isAvailable()) {
        reject(new Error('IndexedDB is not available'));
        return;
      }

      const request = indexedDB.open(dbName, 1);

      request.onupgradeneeded = (event) => {
        this.db = event.target.result;
        if (!this.db.objectStoreNames.contains(storeName)) {
          this.db.createObjectStore(storeName, { keyPath: 'id' });
        }
      };

      request.onsuccess = (event) => {
        this.db = event.target.result;
        resolve(this.db);
      };

      request.onerror = (event) => {
        console.error('IndexedDB error:', event.target.error);
        reject(event.target.error);
      };
    });
  }

  /**
   * 设置数据
   * @param {string} key - 键名
   * @param {any} value - 值
   * @param {Object} options - 选项
   * @returns {Promise<boolean>} 是否成功
   */
  async set(key, value, options = {}) {
    if (!this.isAvailable()) {
      console.error('IndexedDB is not available');
      return false;
    }

    try {
      if (!this.db) {
        await this.initIndexedDB();
      }

      return new Promise((resolve, reject) => {
        const transaction = this.db.transaction([this.storeName], 'readwrite');
        const store = transaction.objectStore(this.storeName);
        const request = store.put({ id: key, value });

        request.onsuccess = () => resolve(true);
        request.onerror = () => reject(request.error);
      });
    } catch (e) {
      console.error('Error setting IndexedDB item:', e);
      return false;
    }
  }

  /**
   * 获取数据
   * @param {string} key - 键名
   * @param {Object} options - 选项
   * @returns {Promise<any>} 值
   */
  async get(key, options = {}) {
    if (!this.isAvailable()) {
      console.error('IndexedDB is not available');
      return null;
    }

    try {
      if (!this.db) {
        await this.initIndexedDB();
      }

      return new Promise((resolve, reject) => {
        const transaction = this.db.transaction([this.storeName], 'readonly');
        const store = transaction.objectStore(this.storeName);
        const request = store.get(key);

        request.onsuccess = () => resolve(request.result ? request.result.value : null);
        request.onerror = () => reject(request.error);
      });
    } catch (e) {
      console.error('Error getting IndexedDB item:', e);
      return null;
    }
  }

  /**
   * 删除数据
   * @param {string} key - 键名
   * @param {Object} options - 选项
   * @returns {Promise<boolean>} 是否成功
   */
  async remove(key, options = {}) {
    if (!this.isAvailable()) {
      console.error('IndexedDB is not available');
      return false;
    }

    try {
      if (!this.db) {
        await this.initIndexedDB();
      }

      return new Promise((resolve, reject) => {
        const transaction = this.db.transaction([this.storeName], 'readwrite');
        const store = transaction.objectStore(this.storeName);
        const request = store.delete(key);

        request.onsuccess = () => resolve(true);
        request.onerror = () => reject(request.error);
      });
    } catch (e) {
      console.error('Error removing IndexedDB item:', e);
      return false;
    }
  }

  /**
   * 清空存储
   * @param {Object} options - 选项
   * @returns {Promise<boolean>} 是否成功
   */
  async clear(options = {}) {
    if (!this.isAvailable()) {
      console.error('IndexedDB is not available');
      return false;
    }

    try {
      if (!this.db) {
        await this.initIndexedDB();
      }

      return new Promise((resolve, reject) => {
        const transaction = this.db.transaction([this.storeName], 'readwrite');
        const store = transaction.objectStore(this.storeName);
        const request = store.clear();

        request.onsuccess = () => resolve(true);
        request.onerror = () => reject(request.error);
      });
    } catch (e) {
      console.error('Error clearing IndexedDB:', e);
      return false;
    }
  }

  /**
   * 获取所有键
   * @param {Object} options - 选项
   * @returns {Promise<string[]>} 键数组
   */
  async keys(options = {}) {
    if (!this.isAvailable()) {
      console.error('IndexedDB is not available');
      return [];
    }

    try {
      if (!this.db) {
        await this.initIndexedDB();
      }

      return new Promise((resolve, reject) => {
        const transaction = this.db.transaction([this.storeName], 'readonly');
        const store = transaction.objectStore(this.storeName);
        const request = store.getAllKeys();

        request.onsuccess = () => resolve(request.result);
        request.onerror = () => reject(request.error);
      });
    } catch (e) {
      console.error('Error getting IndexedDB keys:', e);
      return [];
    }
  }
}
